<template>
  <div id="app">
    <el-button type="text" @click="dialogVisible = true">配置公式</el-button>
    <el-form ref="form" :model="formData">
      <el-form-item label="名称">
        <el-input v-model="formData.name"></el-input>
      </el-form-item>
      <el-form-item label="年龄">
        <el-input type="textarea" v-model="formData.age"></el-input>
      </el-form-item>
      <el-form-item label="地址">
        <el-input type="textarea" v-model="formData.desc"></el-input>
      </el-form-item>
    </el-form>
    <div>计算结果：{{ result }}</div>
    <el-dialog title="配置公式" :visible.sync="dialogVisible" width="80%">
      <FormulaEditor
        :formulaTypeList="formulaTypeList"
        ref="formulaEditor"
        :formulaConf="formulaConf"
        :loading="true"
        :fieldList="fieldList"></FormulaEditor>
      <span slot="footer" class="dialog-footer">
        <el-button @click="onCancel">取 消</el-button>
        <el-button type="primary" @click="onConfirm">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
  import formulaTypeListObj from './vue-formula-editor/formula'
  import { compileScript } from './vue-formula-editor/core/compiler'
  import FormulaEditor from './vue-formula-editor/index.vue'
  import functionCall from './vue-formula-editor/core/functionCall'

  export default {
    name: 'HomeView',
    components: {
      FormulaEditor,
    },
    data() {
      return {
        dialogVisible: false,
        formData: {
          name: '小明',
          desc: '合肥市',
          age: 18,
        },
        result: '',
        formulaTypeList: [],
        // 公式
        formulaConf: {
          "text": "return CONCATENATE(用户名,' = ',用户名)",
          "marks": [
            {
              "from": {
                "line": 0,
                "ch": 19,
                "sticky": null
              },
              "to": {
                "line": 0,
                "ch": 22,
                "sticky": null
              },
              "fieldCode": "name",
              "markType": "fieldName",
              "fieldPath": "name"
            },
            {
              "from": {
                "line": 0,
                "ch": 29,
                "sticky": null
              },
              "to": {
                "line": 0,
                "ch": 32,
                "sticky": null
              },
              "fieldCode": "name",
              "markType": "fieldValue",
              "fieldPath": "name"
            }
          ]
        },
        watchData: null,
        fieldList: [
          {
            fieldName: '用户名',
            fieldType: 'string',
            fieldCode: 'name',
            fieldPath: 'name',
            children: []
          },
          {
            fieldName: '年龄',
            fieldType: 'number',
            fieldCode: 'age',
            fieldPath: 'age',
            children: []
          }
        ],
      }
    },
    mounted() {
      this.formulaTypeList = formulaTypeListObj.map(ObjInstance => new ObjInstance())
    },
    methods: {
      /**
       * 必须实现的方法，根据传入的 fieldPath 来获取字段/变量名称
       * @param fieldPath
       * @returns {*}
       */
      getFieldName(fieldPath) {
        return fieldPath
      },
      /**
       * 必须实现的方法，根据传入的 fieldPath 来获取字段/变量值，其中 fieldPath 支持多级路径，如：form.user.phone
       * @param fieldPath
       * @returns {*}
       */
      getFieldValue(fieldPath) {
        return this.formData[fieldPath]
      },
      onConfirm() {
        const data = this.$refs.formulaEditor.getData()
        console.log('编辑器数据结构', JSON.stringify(data))
        this.formulaConf = data
        this.dialogVisible = false
        let compileScriptStr = compileScript({
           marks: this.formulaConf.marks,
          text: this.formulaConf.text
        })
        console.log('编译后的脚本', compileScriptStr)
        let funResp = functionCall.execute(compileScriptStr, this)
        this.result = funResp
      },
      onCancel() {
        this.dialogVisible = false
      },
      resetFormula() {
        this.$refs.formulaEditor.reset()
      }
    },
  }
</script>

<style></style>
